﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Galaxy.ModuleInterface.Messages;
using Galaxy.ModuleInspector.Events;
using Galaxy.ModuleInterface.Messages.Source;
using Galaxy.ModuleInterface.Messages.Destination;
using Galaxy.ModuleInterface;
using System.Collections;

namespace Galaxy.ModuleInspector
{
    internal partial class ModuleInspector_Form : Form
    {
        /* ---------------------------------------------------------------------- */

        private GalaxyModuleInspector f_ModuleInspector;

        /* ---------------------------------------------------------------------- */

        public GalaxyModuleInspector ModuleInspector
        {
            get { return f_ModuleInspector; }
            set
            {
                if(value == f_ModuleInspector) return;

                InspectorDisconnected(f_ModuleInspector);
                f_ModuleInspector = value;
                InspectorConnected(value);
            }
        }

        /// <summary>Выбранный модуль</summary>
        protected IGalaxyModule SelectedModule
        {
            get { return (IGalaxyModule)ConnectedModules_ListBox.SelectedItem; }
            set { ConnectedModules_ListBox.SelectedItem = value; }
        }

        protected IGalaxyModule[] SelectedModules
        {
            get
            {
                IGalaxyModule[] ConnectedModules = new IGalaxyModule[ConnectedModules_ListBox.SelectedItems.Count];
                int i = 0;
                foreach(object ConnectedItem in ConnectedModules_ListBox.SelectedItems)
                    ConnectedModules[i++] = (IGalaxyModule)ConnectedItem;
                return ConnectedModules;
            }
            set
            {
                // Добавление модулей в список выделенных
                Array.ForEach<IGalaxyModule>(value, delegate(IGalaxyModule ConnectedModule)
                {
                    for(int i = 0, i_Length = ConnectedModules_ListBox.Items.Count; i < i_Length; i++)
                        if((IGalaxyModule)ConnectedModules_ListBox.Items[i] == ConnectedModule)
                        {
                            i = i_Length;
                            for(int j = 0, j_Length = ConnectedModules_ListBox.SelectedItems.Count;
                                j < j_Length; j++)
                                if((IGalaxyModule)ConnectedModules_ListBox.SelectedItems[j] == ConnectedModule)
                                    return;
                            ConnectedModules_ListBox.SelectedItems.Add(ConnectedModule);
                        }
                });

                // Удаление модулей, не присутствующих в списке выделенных
                List<object> lv_NotConnected = new List<object>(ConnectedModules_ListBox.SelectedItems.Count);
                foreach(object Module in ConnectedModules_ListBox.SelectedItems)
                    if(!Array.Exists<IGalaxyModule>(value, Module.Equals))
                        lv_NotConnected.Add(Module);
                lv_NotConnected.ForEach(ConnectedModules_ListBox.SelectedItems.Remove);
            }
        }

        /* ---------------------------------------------------------------------- */

        public ModuleInspector_Form()
        {
            InitializeComponent();
        }

        /* ---------------------------------------------------------------------- */

        private delegate void InspectorDelegate(GalaxyModuleInspector Inspector);

        private void InspectorConnected(GalaxyModuleInspector Inspector)
        {
            if(this.InvokeRequired)
                this.Invoke(new InspectorDelegate(InspectorConnected), Inspector);
            else
                if(Inspector != null)
                {
                    ConnectedModules_ListBox.Items.Clear();
                    ReceivedMessages_ListBox.Items.Clear();

                    ConnectedModules_ListBox.Items.AddRange(
                        Inspector.ConnectedModules.ToArray());

                    f_ModuleInspector.OnModuleConnected += ModuleConnected;
                    f_ModuleInspector.OnModuleDisconnected += ModuleDisconnected;
                }
        }

        private void InspectorDisconnected(GalaxyModuleInspector Inspector)
        {
            if(this.InvokeRequired)
                this.Invoke(new InspectorDelegate(InspectorDisconnected), Inspector);
            else
                if(Inspector != null)
                {
                    ConnectedModules_ListBox.Items.Clear();

                    f_ModuleInspector.OnModuleConnected -= ModuleConnected;
                    f_ModuleInspector.OnModuleDisconnected -= ModuleDisconnected;
                }
        }

        public void ModuleConnected(GalaxyModuleInspector Inspector,
            Events.OnModuleConnectedEventArgs Arg)
        {

            if(this.InvokeRequired)
                this.Invoke(new OnModuleConnectedEventHandler(
                    ModuleConnected), Inspector, Arg);
            else
                ConnectedModules_ListBox.Items.Add(Arg.Module);
        }

        public void ModuleDisconnected(GalaxyModuleInspector Inspector,
            Events.OnModuleConnectedEventArgs Arg)
        {
            if(this.InvokeRequired)
                this.Invoke(new OnModuleConnectedEventHandler(
                    ModuleDisconnected), Inspector, Arg);
            else
                ConnectedModules_ListBox.Items.Remove(Arg.Module);
        }

        private delegate void ShowMessageDelegate(IGalaxyModuleMessage Message);
        public void ShowMessage(IGalaxyModuleMessage Message)
        {
            if(this.InvokeRequired)
                this.Invoke(new ShowMessageDelegate(ShowMessage), Message);
            else
                if(Message != null)
                {
                    ReceivedMessages_ListBox.Items.Insert(0, Message);
                }
        }

        private delegate void NonArgumentDelegate();

        internal void CloseForm()
        {
            if(this.InvokeRequired)
                this.Invoke(new NonArgumentDelegate(CloseForm));
            else
                this.Close();
        }

        private void RepeatMessage_Button_Click(object sender, EventArgs e)
        {
            if(ModuleInspector == null) return;
            for(int i = 0; i < ReceivedMessages_ListBox.SelectedItems.Count; i++)
            {
                IGalaxyModuleMessage Message =
                    ReceivedMessages_ListBox.SelectedItems[i] as IGalaxyModuleMessage;
                if(Message != null)
                    ModuleInspector.SendMessage((IGalaxyModuleMessage)Message.Clone());
            }

        }

        private void ReSendMessage_Button_Click(object sender, EventArgs e)
        {
            if(ModuleInspector == null) return;
            for(int i = 0; i < ReceivedMessages_ListBox.SelectedItems.Count; i++)
            {
                IGalaxyModuleMessage MessageToSend =
                    ReceivedMessages_ListBox.SelectedItems[i] as IGalaxyModuleMessage;
                if(MessageToSend != null)
                {
                    MessageToSend = (IGalaxyModuleMessage)MessageToSend.Clone();
                    MessageToSend.Source = new ModuleSource(ModuleInspector);
                    IGalaxyModule[] Distination =
                        new IGalaxyModule[ConnectedModules_ListBox.SelectedItems.Count];
                    for(int j = 0; j < Distination.Length; j++)
                        Distination[j] = (IGalaxyModule)ConnectedModules_ListBox.SelectedItems[j];

                    MessageToSend.Destination = new CDestination(Distination);
                    ModuleInspector.SendMessage(MessageToSend);
                }
            }
        }

        private void LoadModule_ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ModuleLoader.ModuleLoader_Form Loader = new Galaxy.ModuleInspector.ModuleLoader.ModuleLoader_Form();

            Loader.FormClosed += Loader_FormClosed;
            Loader.ShowDialog(this);
        }

        private void Loader_FormClosed(object sender, FormClosedEventArgs e)
        {
            ModuleLoader.ModuleLoader_Form Loader = (ModuleLoader.ModuleLoader_Form)sender;

        }           

        private void Stop_ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<IGalaxyModule> lv_Connected = new List<IGalaxyModule>();
            foreach(object Object in ConnectedModules_ListBox.SelectedItems)
                if(Object is IGalaxyModule)
                    lv_Connected.Add(Object as IGalaxyModule);
            lv_Connected.ForEach(delegate(IGalaxyModule ConnectedModule) { ConnectedModule.Stop(); });
        }

        private void ConnectedModules_ListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            ListBox lv_ModulesList = (ListBox)sender;
            IGalaxyModule lv_SelectedModule = SelectedModule;
            if(lv_ModulesList == null) return;
            IsInitialized_CheckBox.Checked = lv_SelectedModule.Initialized;
            IsStarted_CheckBox.Checked = lv_SelectedModule.Enable;
        }

        private void IsStarted_CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox EnabledCheckBox = (CheckBox)sender;
            this.SelectedModule.Enable = EnabledCheckBox.Checked;
        }

        private void IsInitialized_CheckBox_CheckedChanged(object sender, EventArgs e)
        {
            IGalaxyModule lv_SelectedModule = this.SelectedModule;
            if(!lv_SelectedModule.Initialized) lv_SelectedModule.Initialize();
            ((CheckBox)sender).Checked = lv_SelectedModule.Initialized;
        }

    }
}